using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;


namespace YT.Controls
{
    public partial class TextRadioBox : UserControl
    {

        private TextRadioBoxStyle m_textRadioBoxStyle = TextRadioBoxStyle.Vertical;
        private string m_Text = "";
        private ControlMode m_cmMode;
        private ContextMenu m_contextMenu = null;
        private DateTime m_dtLastKey = new DateTime(1900, 1, 1);
        private Control m_conLastCon = null;
        public delegate void ClickEventHandler(object sender, EventArgs e);

        ToolStripControlHost ListHost;
        ToolStripDropDown dropDown;


        public TextRadioBox()
        {

            ListBox listBox = new ListBox();
            listBox.SelectedIndexChanged += new EventHandler(listBox_SelectedIndexChanged);

            listBox.BorderStyle = BorderStyle.None;
            listBox.Items.Add("Yes");
            listBox.Items.Add("No");
            listBox.Top = 0;
            listBox.Left = 0;
            listBox.TabStop = false;
            ListHost = new ToolStripControlHost(listBox);
            ListHost.AutoSize = false;


            InitializeComponent();
            dropDown = new ToolStripDropDown();
            dropDown.Width = this.txtCheckValue.Width;
            dropDown.Items.Add(ListHost);
            listBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextRadioBox_KeyDown);
            listBox.MouseDoubleClick += new MouseEventHandler(listBox_MouseDoubleClick);
            dropDown.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextRadioBox_KeyDown);
            listBox.MouseDown += new MouseEventHandler(this.txtCheckValue_MouseDown);
            dropDown.MouseDown += new MouseEventHandler(this.txtCheckValue_MouseDown);    

        }

        public delegate void ValueChangedEventHandler(object sender, EventArgs e);
        public event ValueChangedEventHandler ValueChanged;
        protected virtual void OnValueChanged(EventArgs e)
        {
            if (ValueChanged != null)
            {
                ValueChanged(this, e);
            }
        }

        public void listBox_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            dropDown.Close();

            if (GetNextControl(txtCheckValue, true) != null && GetNextControl(txtCheckValue, true).Name == txtCheckValue.Name)
            {
                SendKeys.Send("Tab");
            }
            Application.DoEvents();
        }

        public enum TextRadioBoxStyle
        {
            Horizontal,
            Vertical
        }

        public enum ControlMode
        {
            Common,
            Design
        }


        public new BorderStyle BorderStyle
        {
            get
            {
                return txtCheckValue.BorderStyle;
            }
            set
            {
                txtCheckValue.BorderStyle = value;
                ListBox.BorderStyle = value;
            }
        }

        public ControlMode TextRadioBoxMode
        {
            get
            {
                return m_cmMode;
            }
            set
            {
                m_cmMode = value;
            }
        }

        public override ContextMenu ContextMenu
        {
            get
            {
                return m_contextMenu;
            }
            set
            {
                m_contextMenu = value;
                this.txtCheckValue.ContextMenu = null;

            }
        }

        override public string Text
        {
            get
            {
                return m_Text;
            }
            set
            {
                if (value.ToUpper().Trim() == "FALSE")
                    m_Text = "No";
                else if (value.ToUpper().Trim() == "TRUE")
                    m_Text = "Yes";
                else 
                    m_Text = value;
                SetValue();
            }
        }


        private void SetValue()
        {
            if (this.Text == "")
            {
                this.rbtNo.Checked = true;
                this.ListBox.Text = "No";
            }
            else if (this.Text == "Yes")
            {
                this.ListBox.Text = "Yes";
                this.rbtYes.Checked = true;
                this.rbtNo.Checked = false ;
            }
            else
            {
                this.ListBox.Text = "No";
                this.rbtYes.Checked = false;
                this.rbtNo.Checked = true ;

            }
            this.txtCheckValue.Text = this.Text;
        }

        public TextRadioBoxStyle RadioBoxStyle
        {
            get
            {
                return m_textRadioBoxStyle;
            }
            set
            {
                m_textRadioBoxStyle = value;
                //TextBoxShow();
            }
        }


        private void TextBoxShow()
        {
            if (this.Width > rbtYes.Width + rbtNo.Width + 6)
                this.RadioBoxStyle = TextRadioBoxStyle.Horizontal;
            else
                this.RadioBoxStyle = TextRadioBoxStyle.Vertical;

            if (this.RadioBoxStyle == TextRadioBoxStyle.Horizontal)
            {
                this.rbtYes.Visible = true;
                this.rbtNo.Visible = true;
                this.rbtYes.TabStop = false;
                this.rbtNo.TabStop = false;
                this.txtCheckValue.Visible = true;
                this.txtCheckValue.TabStop = true;
            }
            else
            {
                this.rbtYes.Visible = false;
                this.rbtNo.Visible = false;
                this.rbtYes.TabStop = true ;
                this.rbtNo.TabStop = true ;
                this.txtCheckValue.Visible = true;
                this.txtCheckValue.TabStop = true;
            }
            this.txtCheckValue.Visible = true;
            this.Height = this.txtCheckValue.Height;
            Application.DoEvents();

        }

        private void RadioButtonShow()
        {
            dropDown.Close();
            this.rbtYes.Visible = true;
            this.rbtYes.Height = 15;
            this.rbtYes.Top = 3;
            this.rbtYes.Left = 3;
            this.rbtYes.BackColor = System.Drawing.SystemColors.Window;

            this.rbtNo.Visible = true;
            this.rbtNo.Height = 15;
            this.rbtNo.Top = 3;
            this.rbtNo.Left = this.rbtYes.Width + 6;
            this.rbtNo.BackColor = System.Drawing.SystemColors.Window;

            this.txtCheckValue.Visible = true;
            this.rbtYes.BringToFront();
            this.rbtNo.BringToFront();

            if (this.Text == "Yes")
                this.rbtYes.Focus();
            else
                this.rbtNo.Focus();
            Application.DoEvents();

        }

        private void LstBoxShow()
        {
            if (!this.Enabled) return;
            this.rbtYes.Visible = false;
            this.rbtNo.Visible = false;
            this.txtCheckValue.Visible = true;
            ShowDropDown();

            //if (txtCheckValue.Text == "Yes")
            //{
                 
            //    SendKeys.Send("{UP}");
            //}
            //else
            //{
            //    SendKeys.Send("{Down}");
            //}
            Application.DoEvents();

        }

        private void rbtYes_CheckedChanged(object sender, EventArgs e)
        {
            if (this.RadioBoxStyle == TextRadioBoxStyle.Vertical ) return;
            if (rbtNo.Checked)
            {
                this.Text = "No";
                this.txtCheckValue.Text = "No";
            }
            else if (rbtYes.Checked)
            {
                this.Text = "Yes";
                this.txtCheckValue.Text = "Yes";
            }
            else
            {
                this.Text = "";
                this.txtCheckValue.Text = "";
            }
            this.ListBox.Text = this.txtCheckValue.Text;

        }

        private void rbtNo_CheckedChanged(object sender, EventArgs e)
        {
            if (this.RadioBoxStyle == TextRadioBoxStyle.Vertical) return;
            if (rbtNo.Checked)
            {
                this.Text = "No";
                this.txtCheckValue.Text = "No";
            }
            else if (rbtYes.Checked)
            {
                this.Text = "Yes";
                this.txtCheckValue.Text = "Yes";
            }
            else
            {
                this.Text = "";
                this.txtCheckValue.Text = "";
            }
            this.ListBox.Text = this.txtCheckValue.Text;
        }

        private void TextRadioBox_Resize(object sender, EventArgs e)
        {
            this.Height = this.txtCheckValue.Height;
            this.txtCheckValue.Width = this.Width;
            this.rbtYes.Location = new Point((this.Width - this.rbtYes.Width - this.rbtNo.Width) / 3, 0);
            this.rbtNo.Location = new Point((this.Width - this.rbtYes.Width - this.rbtNo.Width) / 3 * 2 + this.rbtYes.Width, 0);
            this.ListBox.Width = this.Width;
        }

        private void TextRadioBox_Load(object sender, EventArgs e)
        {
            this.txtCheckValue.Top = 0;
            this.txtCheckValue.Left = 0;
            this.ListBox.Left = 0;
            this.Height = this.txtCheckValue.Height;
            this.txtCheckValue.Width = this.Width;
            this.rbtYes.Location = new Point((this.Width - this.rbtYes.Width - this.rbtNo.Width) / 3, 0);
            this.rbtNo.Location = new Point((this.Width - this.rbtYes.Width - this.rbtNo.Width) / 3 * 2 + this.rbtYes.Width, 0);
            this.ListBox.Width = this.Width;
            TextBoxShow();
        }

        private void TextRadioBox_Leave(object sender, EventArgs e)
        {
            TextBoxShow();
           // if(this.FindForm()!=null)  this.FindForm().Activate();
            dropDown.Hide(); 
            Application.DoEvents();

        }

        public void listBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.Text = ListBox.Text;
            this.txtCheckValue.Text = ListBox.Text;
            if (ListBox.Text == "Yes")
            {
                this.rbtYes.Checked = true;
                this.rbtNo.Checked = false;
            }
            else
            {
                this.rbtYes.Checked = false;
                this.rbtNo.Checked = true;
            }
           // dropDown.Close();

            Application.DoEvents();
        }

        public ListBox ListBox
        {
            get { return ListHost.Control as ListBox; }
        }
        private void ShowDropDown()
        {
            if (dropDown != null)
            {

                ListHost.Margin = new Padding(-1, -2, -1, -1);
                ListHost.Size = new Size(this.txtCheckValue.Width, this.txtCheckValue.Height * 2 - 10);

                dropDown.Show(this, 0, this.Height);
                dropDown.Focus();
                ListHost.Focus();
                ListBox.Focus();  
            }
        }


        private void txtCheckValue_TextChanged(object sender, EventArgs e)
        {
            base.OnTextChanged(e);
            this.OnValueChanged(e);
        }

        private void TextRadioBox_Enter(object sender, EventArgs e)
        {
            if (Application.ProductName.IndexOf("Microsoft") >= 0) return;
            this.Text = this.txtCheckValue.Text;  
            if (this.RadioBoxStyle == TextRadioBoxStyle.Horizontal)
            {
                RadioButtonShow();
            }
            else
            {
                LstBoxShow();
            }
            Application.DoEvents();
        }



        private void TextRadioBox_Click(object sender, EventArgs e)
        {
            if (this.RadioBoxStyle == TextRadioBoxStyle.Horizontal)
            {
                RadioButtonShow();
            }
            else
            {
                LstBoxShow();
                Application.DoEvents();
            }
        }



        private void TextRadioBox_EnabledChanged(object sender, EventArgs e)
        {
            if (this.Enabled)
            {
                txtCheckValue.ReadOnly = true ;
                txtCheckValue.BackColor = System.Drawing.SystemColors.Window;
                txtCheckValue.ForeColor = System.Drawing.SystemColors.WindowText ;
            }
            else
            {
                txtCheckValue.ReadOnly = true ;
                txtCheckValue.BackColor = System.Drawing.SystemColors.Control;
                dropDown.Hide(); 
            }
        }
        public void HideDropDown()
        {
            dropDown.Hide(); 
        }

        private void TextRadioBox_KeyDown(object sender, KeyEventArgs e)
        {
            Control con = sender as Control;
            if (e.KeyCode  == Keys.Enter )
            {

                if(dropDown.Visible ) dropDown.Close();

                if (GetNextControl(this, true) != null )
                {
                    this.Focus(); 
                    SendKeys.Send("Tab");
                }

                Application.DoEvents();
            }
            else if ( con!=null && con.Name == txtCheckValue.Name &&  e.KeyCode == Keys.Down)
            {
                TextRadioBox_Click(txtCheckValue, new EventArgs());  
            }
        }

        private void txtCheckValue_DoubleClick(object sender, EventArgs e)
        {
            TextRadioBox_Enter(sender, e);
        }

        private void txtCheckValue_MouseDown(object sender, MouseEventArgs e)
        {
            base.OnMouseDown(e);  
        }

        private void txtCheckValue_MouseClick(object sender, MouseEventArgs e)
        {
            base.OnMouseClick(e); 
        }

        private void rbt_Click(object sender, System.EventArgs e)
        {
            RadioButton rbt = sender as RadioButton;
            if (rbt == null) { return; }

            if (IsDoubleClickRadioButton(rbt))
            {
                this.rbtYes.Visible = false;
                this.rbtNo.Visible = false;
                this.txtCheckValue.Focus();
                SendKeys.Send("{TAB}");
            }
            Application.DoEvents();
        }

        private bool IsDoubleClickRadioButton(RadioButton rbt)
        {
            bool bIsDoubleClick = false;

            DateTime dtNowKey = System.DateTime.Now;
            TimeSpan tsTime = (TimeSpan)(System.DateTime.Now - m_dtLastKey);
            if ((m_conLastCon != null && rbt.Name == m_conLastCon.Name) && (tsTime.Days == 0 && 
                tsTime.Hours == 0 && tsTime.Minutes == 0  && tsTime.Seconds == 0 && tsTime.Milliseconds < 1000))
            {
                bIsDoubleClick = true;
            }
            m_dtLastKey = dtNowKey;
            m_conLastCon = rbt;

            return bIsDoubleClick;
        }

        protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData)
        {
            int WM_KEYDOWN = 256;
            int WM_SYSKEYDOWN = 260;

            if (this.RadioBoxStyle == TextRadioBoxStyle.Horizontal)
            {
                if (msg.Msg == WM_KEYDOWN | msg.Msg == WM_SYSKEYDOWN)
                {
                    switch (keyData)
                    {
                        case Keys.Left:
                        case Keys.Right:
                            if (rbtYes.Checked)
                                this.rbtNo.Focus();
                            else
                                this.rbtYes.Focus();
                            return true;
                        default:
                            return base.ProcessCmdKey(ref msg, keyData);
                    }
                }
            }
            else
            {
                return base.ProcessCmdKey(ref msg, keyData);
            }

            return false;
        }
    }
}